iT邦幫忙

2023 iThome 鐵人賽

DAY 29
0
SideProject30

初探 Godot系列 第 29

[DAY 29] 紀錄分數 (FileAccess)

  • 分享至 

  • xImage
  •  

今日目標:在遊戲中紀錄分數


▍事前準備

我們的遊戲現在只會在結束時顯示一次分數,這樣就少了一點樂趣。因此今天我們將最高的分數紀錄到檔案系統中保存,並在遊戲結束時顯示。
儲存到檔案系統也可以讓我們在關閉遊戲後仍然保存著我們的資料並在下一次啟動時回復資料,大部分的遊戲中會是很重要的功能!

這次的程式修改主要是使用官方範例做些微調整,可以到官網看更詳細介紹。

  • 介紹 FileAccess

    Provides methods for file reading and writing operations.

    This class can be used to permanently store data in the user device's file system and to read from it. This is useful for store game save data or player configuration files.

      這個類別讓我們能夠儲存一些永久性的資料並從中讀取,可以用來儲存遊戲資料以及玩家資訊等等。
    

▍出發

  • 儲存檔案
    1. 宣告變數紀錄最高分數以及要儲存的檔案路徑。
    var highest_score: float = 0.00
    var saved_location: String = "user://savegame.save"
    
    1. 撰寫儲存結果的方法。
    func save_game():
        # 從我們的顯示分數的 label 取得此次的分數。
        var score = float(score_label.text)
        # 若大於最高分則更新結果並儲存到檔案系統中。
        if score > highest_score:
            # 更新紀錄。
            highest_score = score
            # 以寫入權限開啟檔案。
            var save_game = FileAccess.open(saved_location, FileAccess.WRITE)
            var save_dict = {
                "highest_score" : str(highest_score)
            }
            # 轉為 json 格式。
            var json_string = JSON.stringify(save_dict)
            # 寫入檔案
            save_game.store_line(json_string)
            # 離開後自動關閉檔案。
    
    1. 在主場景處理遊戲結束時觸發儲存邏輯。
    func handle_game_end():
        # ...
        hud.save_game()
    
  • 讀取檔案
    1. 撰寫讀取檔案方法
    func load_game():
        # 如果檔案不存在則不做處理。
        if not FileAccess.file_exists(saved_location):
            return
        # 以讀取權限開啟檔案。
        var save_game = FileAccess.open(saved_location, FileAccess.READ)
        # 如果現在的位置還沒有到檔案總長則繼續讀取。
        while save_game.get_position() < save_game.get_length():
    
            # 讀取行。
            var json_string = save_game.get_line()
    
            # 解析 json 格式
            var json = JSON.new()
            var parse_result = json.parse(json_string)
    
            # 若錯誤顯示錯誤訊息
            if not parse_result == OK:
                print("JSON Parse Error: ", json.get_error_message(), " in ", json_string, " at line ", json.get_error_line())
                continue
    
            # 獲得結果字典
            var data = json.get_data()
    
            # 取出需要的值
            highest_score = float(data["highest_score"])
    
    1. 在啟動遊戲時進行讀取並初始化顯示畫面。
    func _ready():
        # ...
        load_game()
        message_label.text = "Highest score : \n" + str(highest_score) + "\n\nRUN!!"
    
  • 查看檔案位置
    如果想要看檔案儲存的位置可以從上方 專案 -> 打開使用者資料資料夾 下找到。
    https://ithelp.ithome.com.tw/upload/images/20231014/2016287502lnRTlgzf.png

▍執行

Yes

▍完成

HUD 檔案

extends CanvasLayer

signal game_start
signal game_pause
signal game_unpause

var message_label:Label
var score_label:Label
var start_button:Button
var pause_button:Button
var message_timer:Timer

var is_stop:bool = false

# record highest score
var highest_score: float = 0.00
var saved_location: String = "user://savegame.save"
	
func _ready():
	message_label = $Message
	score_label = $Score
	start_button = $StartButton
	pause_button = $PauseButton
	message_timer = $MessageTimer
	
	start_button.pressed.connect(_on_start_button_pressed)
	pause_button.pressed.connect(_on_pause_button_pressed)
	message_timer.timeout.connect(_on_message_timer_timout)
	
	load_game()
	message_label.text = "Highest score : \n" + str(highest_score) + "\n\nRUN!!"

	
func _on_start_button_pressed():
	# ...
func _on_pause_button_pressed():
	# ...
func _on_message_timer_timout():
	# ...
func show_message(text: String, wait_time: float=2):
	# ...
func show_game_start():
	# ...
func show_game_pause():
	# ...
func show_game_unpause():
	# ...
func show_game_over():
	# ...
func update_score(score):
	# ...

func load_game():
	if not FileAccess.file_exists(saved_location):
		return
	var save_game = FileAccess.open(saved_location, FileAccess.READ)
	while save_game.get_position() < save_game.get_length():
		var json_string = save_game.get_line()
		var json = JSON.new()
		var parse_result = json.parse(json_string)
		if not parse_result == OK:
			print("JSON Parse Error: ", json.get_error_message(), " in ", json_string, " at line ", json.get_error_line())
			continue

		var data = json.get_data()
		
		highest_score = float(data["highest_score"])

func save_game():
	var score = float(score_label.text)
	if score > highest_score:
		highest_score = score
		var save_game = FileAccess.open(saved_location, FileAccess.WRITE)
		var save_dict = {
			"highest_score" : str(highest_score)
		}
		var json_string = JSON.stringify(save_dict)
		save_game.store_line(json_string)

:)


上一篇
[DAY 28] 暫停功能
下一篇
[DAY 30] 匯出專案
系列文
初探 Godot30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言